package tgc.edu.tms.web.controller;

import java.sql.Date;
import java.util.HashSet;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import tgc.edu.tms.custom.AjaxResult;
import tgc.edu.tms.custom.CommonController;
import tgc.edu.tms.custom.TablePageable;
import tgc.edu.tms.custom.TimeUtils;
import tgc.edu.tms.entity.Callnames;
import tgc.edu.tms.entity.FlowTable;
import tgc.edu.tms.entity.Schedule;
import tgc.edu.tms.entity.Student;
import tgc.edu.tms.security.UserUtils;
import tgc.edu.tms.service.CallnamesService;
import tgc.edu.tms.service.FlowTableService;
import tgc.edu.tms.service.ScheduleService;
import tgc.edu.tms.service.StudentService;
import tgc.edu.tms.web.form.CallnamesForm;

@Controller
@RequestMapping(value = "/callnames")
public class CallnamesController {

	@Autowired
	private FlowTableService flowTableService;
	@Autowired
	private StudentService studentService;
	@Autowired
	private CallnamesService callnamesService;
	@Autowired
	private UserUtils userUtils;
	
	/**
	 * 点名系统
	 * @param map
	 * @param session
	 * @return
	 */
	@RequestMapping(value="/dianming")
	public String diannming(ModelMap map,HttpSession session) {
		Specification<FlowTable> spec = new Specification<FlowTable>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<FlowTable> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				rules.add(cb.equal(root.get("time"), TimeUtils.getStringTime())); 
				rules.add(cb.equal(root.get("teacher"), userUtils.getUser().getName()));
				rules.add(cb.equal(root.get("jc"), TimeUtils.getJc(TimeUtils.getTime())));
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		List<FlowTable> findAll = flowTableService.findAll(spec);
		FlowTable flowTable = new FlowTable();
		if(findAll.size()!=0) {
			flowTable = findAll.get(0);
			session.setAttribute("flowTable", flowTable);
			session.setMaxInactiveInterval(30*60);
		}else {
			flowTable.setTeacher(userUtils.getUser().getName());
			flowTable.setTime(TimeUtils.getStringTime());
		}
		map.put("f", flowTable);
		return "callnames/dianming";
	}
	
	/**
	 * 学生加载
	 * @param pageParam
	 * @param session
	 * @return
	 */
	@RequestMapping(value="/page")
	@ResponseBody
	public Object page(TablePageable pageParam,HttpSession session) {
		//PageRequest pageable = pageParam.bulidPageRequest();
		FlowTable flowTable = (FlowTable) session.getAttribute("flowTable");
		if(flowTable!=null) {
		String classes = flowTable.getClasses();
		String year = flowTable.getYear();
			String[] names=getclassname(classes);
			List<Callnames> callnames = callnamesService.findAll(findspec1(names).and(findspec4(flowTable.getJc(),TimeUtils.getNowTime())));
			List<Student> page = studentService.findAll(findspec(names).and(findspec2(callnames,year)));
			return page;	
		}else {
			return null;
		}
	}
	
	
	

	/**
	 * 已到
	 * @param form
	 * @param session
	 * @return
	 */
	@RequestMapping(value="/isreach")
	@ResponseBody
	public Object isreach(CallnamesForm form,HttpSession session) {
		try {
			FlowTable flowTable = (FlowTable) session.getAttribute("flowTable");
				form.setJc(flowTable.getJc());
				form.setKc(flowTable.getCourse());
				form.setTeacher(flowTable.getTeacher());
				if(isStudent(form)) {
					Student student = studentService.findById(form.getId());
					Callnames model= new Callnames();
					model.setTeacher(form.getTeacher());
					model.setIsReach(form.getIsReach());
					model.setJc(form.getJc());
					model.setKc(form.getKc());
					model.setTime(TimeUtils.getNowTime());
					model.setStudent(student);
					model.setBanji(student.getTbclass());
					callnamesService.save(model);
					if(flowTable.getSdrs()==null) {
						flowTable.setSdrs(1);
					}else {
						flowTable.setSdrs(flowTable.getSdrs()+1);
					}
					flowTableService.save(flowTable);
				return new AjaxResult("点名成功！");
			}else {
				return new AjaxResult("该生已点名！");
			}
		} catch (Exception e) {
			return new AjaxResult(false,"点名失败！");
		}
		
	}
	
	/**
	 * 未到、请假
	 * @param form
	 * @param session
	 * @return
	 */
	@RequestMapping(value="/isreach1")
	@ResponseBody
	public Object isreach1(CallnamesForm form,HttpSession session) {
		try {
			FlowTable flowTable = (FlowTable) session.getAttribute("flowTable");
				form.setJc(flowTable.getJc());
				form.setKc(flowTable.getCourse());
				form.setTeacher(flowTable.getTeacher());
				if(isStudent(form)) {
					Student student = studentService.findById(form.getId());
					Callnames model= new Callnames();
					model.setTeacher(form.getTeacher());
					model.setIsReach(form.getIsReach());
					model.setJc(form.getJc());
					model.setKc(form.getKc());
					model.setTime(TimeUtils.getNowTime());
					model.setBanji(student.getTbclass());
					model.setStudent(student);
					callnamesService.save(model);
				return new AjaxResult("操作成功！");
			}else {
				return new AjaxResult("该操作已生效！");
			}
		} catch (Exception e) {
			return new AjaxResult(false,"操作失败！");
		}
		
	}
	
	
	/***
	 * 全勤
	 * @param session
	 * @return
	 */
	@RequestMapping(value="/isreach2")
	@ResponseBody
	public Object isreach2(HttpSession session) {
		try {
			FlowTable flowTable = (FlowTable) session.getAttribute("flowTable");
			if(flowTable!=null) {
				String classes = flowTable.getClasses();
				String[] names=getclassname(classes);
				String year = flowTable.getYear();
				List<Callnames> callnames = callnamesService.findAll(findspec1(names).and(findspec4(flowTable.getJc(),TimeUtils.getNowTime())));
				List<Student> students = studentService.findAll(findspec(names).and(findspec2(callnames,year)));
				if(students.size()!=0) {
					for (Student student : students) {
						Callnames model= new Callnames();
						model.setTeacher(flowTable.getTeacher());
						model.setIsReach("已到");
						model.setJc(flowTable.getJc());
						model.setKc(flowTable.getCourse());
						model.setTime(TimeUtils.getNowTime());
						model.setBanji(student.getTbclass());
						model.setStudent(student);
						callnamesService.save(model);
						if(flowTable.getSdrs()==null) {
							flowTable.setSdrs(1);
						}else {
							flowTable.setSdrs(flowTable.getSdrs()+1);
						}
						flowTableService.save(flowTable);
					}
					return new AjaxResult("操作成功！");
			  }else {
				  return new AjaxResult("操作无效！");
			  }
			}else {
				return new AjaxResult("操作无效！");
			}
		} catch (Exception e) {
			return new AjaxResult(false,"操作失败！");
		}
		
	}




	private boolean isStudent(CallnamesForm form) {
		Specification<Callnames> spec = new Specification<Callnames>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<Callnames> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				rules.add(cb.equal(root.get("time"), TimeUtils.getNowTime()));
				rules.add(cb.equal(root.get("teacher"), form.getTeacher()));
				rules.add(cb.equal(root.get("jc"), form.getJc()));
				rules.add(cb.equal(root.get("student").get("id"), form.getId()));
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		List<Callnames> list = callnamesService.findAll(spec);
		if(list.size()==0) {
			return true;
		}else {
			return false;
		}
	}





	/***
	 * 根据班级名称生成条件
	 * @param names
	 * @param year 
	 * @param callnames 
	 * @return
	 */
	private Specification<Student> findspec(String[] names) {
		Specification<Student> spec = new Specification<Student>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if(names.length!=0) {	
					for(int i = 0 ; i<names.length ; i++) {
						String name = names[i];
						rules.add(cb.equal(root.get("tbClass").get("name"), name)); 
					}
				}
				return cb.or(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}
	private Specification<Student> findspec2(List<Callnames> callnames, String year) {
		Specification<Student> spec = new Specification<Student>() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if(callnames.size()!=0) {
					for (Callnames callnames2 : callnames) {
						rules.add(cb.notEqual(root.get("id"), callnames2.getStudent().getId())); 
					}
				}
				rules.add(cb.equal(root.get("tbClass").get("profession").get("year"), year));
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}
	private Specification<Callnames> findspec1(String[] names) {
		Specification<Callnames> spec = new Specification<Callnames>() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public Predicate toPredicate(Root<Callnames> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				if(names.length!=0) {	
					for(int i = 0 ; i<names.length ; i++) {
						String name = names[i];
						rules.add(cb.equal(root.get("student").get("tbClass").get("name"), name)); 
					}
				}
				return cb.or(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}
	private Specification<Callnames> findspec4(String jc, Date time) {
		Specification<Callnames> spec = new Specification<Callnames>() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public Predicate toPredicate(Root<Callnames> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				rules.add(cb.equal(root.get("jc"), jc));
				rules.add(cb.equal(root.get("time"), time));
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

	/***
	 * 得到班级名称
	 * @param classname
	 * @return
	 */
	public String[] getclassname(String classname) {
		if (classname.contains(",") || classname.contains("，")) {
			String[] s = null;
			if (classname.contains(",")) {
				s = classname.split(",");
			}
			if (classname.contains("，")) {
				s = classname.split("，");
			}
			return s;
		} else {
			String[] s = { classname };
			return s;
		}
	}
	
	
}
